﻿

using HBase;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Threading;
namespace hconnect {
    // Token: 0x02000009 RID: 9
    public class SiemensConnect :SiemensConnectBase {
        const string write4CMD = "03 00 00 27 02 F0 80 32 01 00 00 99 99 00 0E 00 08 05 01 12 0A 10 02 00 04 {0} 84 00 {1} 00 04 00 20 {2}";
        //const string floatCMD= "03 00 00 27 02 F0 80 32 01 00 00 99 99 00 0E 00 08 05 01 12 0A 10 02 00 04 {0} 84 00 {1} 00 04 00 20 {2}";
        const string write2CMD = "03 00 00 25 02 F0 80 32 01 00 00 99 99 00 0E 00 06 05 01 12 0A 10 02 00 02 {0} 84 00 {1} 00 04 00 10 {2}";
        static byte[] header;
        byte iplast = 0;
        static SiemensConnect() {
            String text11 = "03 00 00 27 02 F0 80 32 01 00 00 99 99 00 0E 00 08 05 01 12 0A 10 02 00 04 0 1 84 00 00 00 00 04 00 20";
            header = Siemens102Util.StrToArraybyte(text11);
        }
        protected virtual int readMaxLen() {
            return 222;
        }
        protected override bool init() {
            base.init();
            iplast = ( byte ) int.Parse(ip.Substring(ip.LastIndexOf(".") + 1));
            return true;
        }
        public byte[] reader(int dbid ,int startAddress ,int readCount) {
            int max = readMaxLen();
            byte[] full = new byte[readCount];
            int offset = 0;
            lock( className ) {
                if( noConn() ) {
                    return null;
                }
                do {
                    if( readCount > max ) {
                        byte[] b = read(dbid ,startAddress ,max);
                        if( b == null ) {
                            return null;
                        }
                        Array.Copy(b ,0 ,full ,offset ,b.Length);
                        offset += max;
                        startAddress += max;
                    } else {
                        byte[] b = read(dbid ,startAddress ,readCount);
                        if( b == null ) {
                            return null;
                        }
                        Array.Copy(b ,0 ,full ,offset ,b.Length);
                    }
                    readCount -= max;
                } while( readCount > 0 );
                return full;
            }
        }
        //03 00 00 1F 02 F0 80 32 01 00 00 00 03 00 0E 00 00 04 01 12 0A 10 02 0 2a 1 F4 84 00 00 00
        //03 00 00 1F 02 F0 80 32 01 00 00 00 03 00 0E 00 00 04 01 12 0A 10 02 0 2a 1 F4 84 00 00 00
        private static Dictionary<long ,byte[]> dict = new Dictionary<long ,byte[]>();
        byte[] getByte(int dbid ,int startAddress ,int readCount) {
            long key = dbid * 10000000l + startAddress * 1000 + readCount;
            lock( dict ) {
                if( !dict.ContainsKey(key) ) {
                    int begin = startAddress * 8;
                    byte[] b = new byte[] { 3 ,0 ,0 ,0X1F ,2 ,0XF0 ,0X80 ,0X32 ,1 ,0 ,0 ,0 ,iplast ,0 ,0X0E ,0 ,0 ,4 ,1 ,0X12 ,0X0A ,0X10 ,2 ,0 ,( byte ) readCount ,( byte ) (dbid / 256) ,( byte ) dbid ,0X84 ,0 ,( byte ) (begin / 256) ,( byte ) begin };
                    dict.Add(key ,b);
                }
                return dict[key];
            }
        }
        // 03   00   00   27    02  F0   80   32   01   00   00   99   99   00   0E   00   08   05   01   12   0A   10   02   00   04   0   1   84   00   0   78    00   04   00   20   0   0   0   1
        // 1     2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26  27  28   29   30   31   32   33   34   35  36   37               
        // -固定-   -报文长度- -------------固定---------------  --序号--  --固定--   -写入+4-  ----------固定--------  -byte -byte个数 ---db- -db-  ---偏移量---  -byte写-- -写入个数-
        //"03   00   00   25   02   F0   80   32   01   00   00   99   99   00   0E   00   06   05   01   12   0A   10   02   00   02   0   1   84   00   00   00   00   04   00   10   0   A"
        //"03   00   00   27   02   F0   80   32   01   00   00   99   99   00   0E   00   08   05   01   12   0A   10   02   00   04   0   1   84   00   00   00   00   04   00   20   7F  FF FF FF"
        public bool writeByteArr(short db ,short addr ,byte[] datas) {
            lock( className ) {
                if( noConn() ) {
                    return false;
                }
                byte[] resArr = new byte[header.Length + datas.Length];
                header.CopyTo(resArr ,0);
                datas.CopyTo(resArr ,header.Length);
                int len = datas.Length;
                resArr[2] = ( byte ) ((35 + len) / 256);
                resArr[3] = ( byte ) ((35 + len) % 256);
                resArr[15] = ( byte ) ((4 + len) / 256);
                resArr[16] = ( byte ) ((4 + len) % 256);
                resArr[23] = ( byte ) (len / 256);
                resArr[24] = ( byte ) (len % 256);
                resArr[25] = ( byte ) (db / 256);
                resArr[26] = ( byte ) (db % 256);
                addr *= 8;
                resArr[28] = ( byte ) (addr / 65536);
                resArr[29] = ( byte ) (addr % 65536 / 256);
                resArr[30] = ( byte ) (addr % 256);
                resArr[33] = ( byte ) ((len * 8) / 256);
                resArr[34] = ( byte ) ((len * 8) % 256);
                return sendOnce(resArr);
            }
        }
        public bool writeInt(short db ,short addr ,int data) {
            lock( className ) {
                if( noConn() ) {
                    return false;
                }
                string text5 = Siemens102Util.ShortTOstr(db);//dbid
                string text6 = Siemens102Util.ShortTOstr(Convert.ToInt16(( int ) (addr * 8)));
                string text9 = Siemens102Util.IntTOstr(data);
                string text11 = string.Format(write4CMD ,text5 ,text6 ,text9);
                return sendOnce(Siemens102Util.StrToArraybyte(text11));
            }
        }
        public bool writeFloat(short db ,short addr ,float data) {
            lock( className ) {
                if( noConn() ) {
                    return false;
                }

                string text5 = Siemens102Util.ShortTOstr(db);//dbid
                string text6 = Siemens102Util.ShortTOstr(Convert.ToInt16(( int ) (addr * 8)));
                string text9 = Siemens102Util.FloatTOstr(data);

                string text11 = string.Format(write4CMD ,text5 ,text6 ,text9);
                return sendOnce(Siemens102Util.StrToArraybyte(text11));
            }
        }

        public bool writeShort(short db ,short addr ,short data) {
            lock( className ) {
                if( noConn() ) {
                    return false;
                }
                bool result = true;
                string text5 = Siemens102Util.ShortTOstr(db);//dbid
                short num = Convert.ToInt16(addr);
                string text6 = Siemens102Util.ShortTOstr(Convert.ToInt16(( int ) (num * 8)));
                string text9 = Siemens102Util.ShortTOstr(data);


                string text11 = string.Format(write2CMD ,text5 ,text6 ,text9);
                return sendOnce(Siemens102Util.StrToArraybyte(text11));
            }
        }
        ///<summary >写入数据</summary>
        public bool writeByte(short db ,short addr ,byte data) {
            lock( className ) {
                if( noConn() ) {
                    return false;
                }
                bool result = true;
                string text5 = Siemens102Util.ShortTOstr(db);//dbid
                short num = Convert.ToInt16(addr);
                string text6 = Siemens102Util.ShortTOstr(Convert.ToInt16(( int ) (num * 8)));
                string text9 = Siemens102Util.ByteTOstr(data);
                String key = "03 00 00 24 02 F0 80 32 01 00 00 99 99 00 0E 00 05 05 01 12 0A 10 02 00 01 {0} 84 00 {1} 00 04 00 08 {2}";
                string text11 = string.Format(key ,text5 ,text6 ,text9);
                return sendOnce(Siemens102Util.StrToArraybyte(text11));
            }
        }
        byte[] read(int dbid ,int startAddress ,int readCount) {
            Send(getByte(dbid ,startAddress ,readCount));
            byte[] array = ReadTelex(readCount + 25);
            int num = array.Length;
            if( num == 19 ) {  //3 0 0 19 2 240 128 50  2 0 0 0 0 0 0 0 0 129 4

                if( array[12] == 220 ) {
                    LoggerCommon.fileAll("请检查：防护与安全》连接级制");
                } else {
                    LoggerCommon.fileAll("检查db块是否建立或者检查读取密码");
                }

                return null;
            } else if( num == 25 ) {
                LoggerCommon.fileAll("需要添加一个s7链接 ");//3 0 0 25 2 240  128 50 3 000 2 0 4 0 04 1 5 000
                return null;
            } else if( num == 25 + readCount ) {
                return array.Skip(25).Take(readCount).ToArray();
            } else {
                return null;
            }
        }
        private bool sendOnce(byte[] packet) {
            Send(packet);
            byte[] array = ReadTelex(256);
            int num = array.Length;
            if( num == 22 && array[20] == 1 && array[21] == 255 ) {
                return true;
            }
            return false;
        }
    }
}